\subsection{Picture Effects (Sigur{\dh}ur Karl)}
My main focus in this project was to create a reflection and a glowing border effect for the pictures.

\subsubsection{Reflection}
The initial idea how we would implement picture reflection was using shaders. This turned out to be more 
complicated than we expected. It was unknown territory and would have required a lot of time to implement. 
We therefore decided to look into other simpler solutions. 

First we looked briefly at dynamic cube maps. This is a form of offscreen rendering to a texture at runtime.
Our experiments with this technique resulted in a strange reflection since the texture was made from 6 
cameras pointing in all directions from the floor object. This approach was therefore abandoned.

The next attempt, and eventually the solution that we ended up using, was simple yet effective and fulfilled 
the requirements for this project. Picture reflection is basically the picture itself turned upside down and 
with some transparency effect to blend it with the environment. We first made a small 10x800 pixel grayscale 
picture with a gradient to represent the picture opacity. When loading a picture we also loaded this gradient as
its alpha channel. The alpha channel image is scaled automatically to the size of the picture.

To create the reflection effect we made a copy of the picture within Panda3D. Since we already have the picture 
that we want to reflect it makes sense to just to copy that picture and use that copy. Next we reposition the reflection image just below the original and pivot it by 180 degrees to set the correct orientation. We then 
scaled down the height of the reflection by 30\% and turned on the transparency for it. Whenever a picture is 
loaded a hidden reflection is created. Showing and hiding the reflection enabled us to turn this effect on and 
off.

The above solution was developed in parallel to the pluggable image loading mechanism. Once we merged the 
reflection code with the rest of the project we ran into a problem with the way the alpha channel was created.
Since different pr3Da plugins load pictures from different sources the Panda3D \textit{loadTexture} method 
could no longer be used. After some experimenting, the only solution we could find to load an alpha channel 
into an PNMImage was to programmatically construct the alpha channel for each image. This meant calculating
the alpha value for each pixel in all the images. This is a very expensive procedure. The time it takes to 
construct a single alpha channel for an 800x600 pixel image is $\sim$ 0.3sec on an Intel\textregistered
Core\texttrademark2 2.53Ghz computer. Construction of an alpha channel is therefore only done once when a 
reflection effect is requested for the picture.

\subsubsection{Glowing}
Another effect that we implemented was to have a glowing border around an image. We found a very good 
example on how to implement this in the Panda3D example code in a sample program called 
"Glow Filter - Advanced". The solution uses shaders to render the glowing effect.

We created a 10x10 pixel grayscale image with a solid 1.0 alpha value. This image was then used as a 
photoframe around a picture and the size scaled to be a 5\% bigger than the picture inside the frame.

The way the glowing works is that the alpha values in the image represent a glow map as opposed to 
transparency. An offscreen buffer is created using a special shader that uses this glow map. This 
offscreen buffer is called the "glow buffer" and its contents are rendered into another offscreen buffer 
called the "blur x buffer" using a shader that does a one-dimensional horizontal blur. The contents of the 
"blur x buffer" are then rendered into a third offscreen buffer called the "blur y buffer" using a shader 
that does a one-dimensional vertical blur.

The result is that the glowing lines that were rendered into the glow buffer form little ``halos''. In the 
end the blurred texture is applied to the main window using additive blending, the halos are added to the 
scene.

We experimented with different offset values for the x and y shaders to obtain an good overall look. 
Using a y value of $3/1024$ and a z value of $5/1024$ produced nice results in our oppinion. We also 
had to add an empty alpha channel to each picture that we loaded using the function \texttt{addAlpha} 
found in the \texttt{PNMImage} class. This was needed because the default value of the alpha channel 
would result in the image itself glowing.